package com.meta.user.controller;


import com.auth0.jwt.exceptions.AlgorithmMismatchException;
import com.auth0.jwt.exceptions.SignatureVerificationException;
import com.auth0.jwt.exceptions.TokenExpiredException;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.meta.common.CommonInfo;
import com.meta.common.ConstDef;
import com.meta.nd.service.NvService;
import com.meta.nd.vo.Nv;
import com.meta.nd.vo.RequestMessage;
import com.meta.nd.vo.RequestMessage2;
import com.meta.nd.vo.ReturnMessage;
import com.meta.user.service.impl.UserService;
import com.meta.user.vo.BindDeviceInfo;
import com.meta.util.ExceptionUtils;
import com.meta.util.JWTUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.Map;

@RestController
@Slf4j
public class UserController {

    @Resource
    private UserService userService;
    @Resource
    private NvService nvService;

    @RequestMapping(value = "/user/login", method = {RequestMethod.POST})
    public ReturnMessage<Nv> login(@RequestBody RequestMessage2<String, String> requestMessage) {
        String userCode = requestMessage.getValue1();
        String password = requestMessage.getValue2();
        CommonInfo commonInfo = requestMessage.getCommonInfo();
        Map<String, Object> map = new HashMap<>();
        if (StringUtils.isEmpty(userCode) ||
                StringUtils.isEmpty(password))
            return ReturnMessage.buildFailMessage("用户代码和密码都不能为空！", "用户代码和密码都不能为空！");
        try {
            boolean passed = userService.verifyUser(userCode, password);
            if (!passed)
                return ReturnMessage.buildFailMessage("用户登录不成功！", "用户代码或者密码不正确！");
            Nv user = nvService.getNvByCode(commonInfo,userCode, "userCode", ConstDef.ND_CODE_USER);
            user.setStringFvByName("password", "*******");
            Map<String, String> payload = new HashMap<>();
            payload.put("userCode", userCode);
            payload.put("name", user.getRawStringByName("userCode"));
            payload.put("id", user.getId().toString());
            String token = JWTUtils.getToken(payload);
            user.setStringFvByName("token", token);
            return new ReturnMessage<Nv>(user, true);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return ExceptionUtils.buildReturnMessage(e);
        }
    }

    @PostMapping("/user/test")
    public ReturnMessage<Boolean> test(String token) {
        log.info("当前token为：[{}]", token);
        Map<String, String> map = new HashMap<>();
        try {
            // 验证令牌
            DecodedJWT verify = JWTUtils.verify(token);
            log.info("用户id：[{}]", verify.getClaim("id").asString());
            log.info("用户名字：[{}]", verify.getClaim("name").asString());
            return new ReturnMessage<Boolean>(true, true);
        } catch (SignatureVerificationException e) {
            log.error(e.getMessage(), e);
            map.put("msg", "无效签名！");
        } catch (TokenExpiredException e) {
            log.error(e.getMessage(), e);
            map.put("msg", "token过期");
        } catch (AlgorithmMismatchException e) {
            log.error(e.getMessage(), e);
            map.put("msg", "算法不一致");
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            map.put("msg", "token无效！");
        }

        return new ReturnMessage<Boolean>(map.get("msg"));
    }

    @RequestMapping(value = "/user/bindDevice", method = {RequestMethod.POST})
    public ReturnMessage<Nv> bindDevice(@RequestBody RequestMessage<BindDeviceInfo> requestMessage) {
        BindDeviceInfo deviceInfo = requestMessage.getValue();
        String userCode = deviceInfo.getUserCode();
        String password = deviceInfo.getPassword();
        String deviceId = deviceInfo.getDeviceId();
        try {
            boolean result = this.userService.bindDevice(deviceId, userCode, password);
            if (result){
                return loginByDeviceId(deviceId);
            }
            else
                return new ReturnMessage<Nv>(null, false);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return ExceptionUtils.buildReturnMessage(e);
        }
    }

    @RequestMapping(value = "/user/loginByDeviceId", method = {RequestMethod.POST})
    public ReturnMessage<Nv> loginByDeviceId(@RequestBody RequestMessage<String> requestMessage) {
        String deviceId = requestMessage.getValue();
        try {
            return loginByDeviceId(deviceId);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return ExceptionUtils.buildReturnMessage(e);
        }
    }

    private ReturnMessage<Nv> loginByDeviceId(String deviceId){
        Nv user = userService.getUserByDeiceId(deviceId);
        String userCode = user.getRawStringByName("userCode");
        user.setStringFvByName("password", "*******");
        Map<String, String> payload = new HashMap<>();
        payload.put("userCode", userCode);
        payload.put("name", user.getRawStringByName("userCode"));
        payload.put("id", user.getId().toString());
        String token = JWTUtils.getToken(payload);
        user.setStringFvByName("token", token);
        return new ReturnMessage<Nv>(user, true);
    }

}

